﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.Common;
using System.Data;
using System.Globalization;
using System.Text;

public partial class CreateVariant : System.Web.UI.Page
{
    private Database db;

    /// <summary>
    /// Initializes the base and destination language listboxes.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
    protected void Page_Load(object sender, EventArgs e)
    {
        if(!Page.IsPostBack) {
            if(db == null || !db.Connected) {
                db = new Database();
                db.OpenConnection();
            }
            using(Database.Command cmd = db.CreateCommand()) {
                cmd.CommandText = "SELECT DISTINCT language FROM " + db.TablePrefix + "resources";
                Database.DataAdapter adapter = new Database.DataAdapter(cmd);
                DataTable dt = new DataTable();
                dt.Columns.Add("language");
                dt.Columns.Add("englishname");
                DbDataReader reader = cmd.ExecuteReader();
                string abbrev;
                while(reader.Read()) {
                    abbrev = reader.GetString(0);
                    if(abbrev.Length > 0) {
                        dt.Rows.Add(abbrev, Utils.GetSafeEnglishName(abbrev));
                    }
                }
                reader.Close();
                dt.DefaultView.Sort = "englishname";
                lstBaseLanguage.DataSource = dt;
                lstBaseLanguage.DataValueField = "language";
                lstBaseLanguage.DataTextField = "englishname";
                lstBaseLanguage.DataBind();
                if(lstBaseLanguage.Items.Count > 0) {
                    mltMain.ActiveViewIndex = 1;
                } else {
                    mltMain.ActiveViewIndex = 0;
                }
                CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
                List<ListItem> availableCultures = new List<ListItem>();
                foreach(CultureInfo culture in cultures) {
                    if(culture.Name.Length > 0) {
                        ListItem itm = new ListItem(culture.EnglishName, culture.Name);
                        availableCultures.Add(new ListItem(culture.EnglishName, culture.Name));
                    }
                }
                availableCultures.Sort(new ListComparer());
                foreach(ListItem itm in availableCultures) {
                    lstDestinationLanguage.Items.Add(itm);
                }
            }
        }
        pnlError.Visible = false;
        pnlSuccess.Visible = false;
    }

    /// <summary>
    /// Checks a source and destinanation language have been selected and they are different
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="System.Web.UI.WebControls.ServerValidateEventArgs"/> instance containing the event data.</param>
    protected void vldLanguages_ServerValidate(object sender, ServerValidateEventArgs e) {
        if(lstBaseLanguage.SelectedItem == null) {
            vldLanguages.ErrorMessage = "The base language must be specified";
            e.IsValid = false;
        } else if(lstDestinationLanguage.SelectedItem == null) {
            vldLanguages.ErrorMessage = "The destination language must be specified";
            e.IsValid = false;
        } else if(lstBaseLanguage.SelectedItem.Value == lstDestinationLanguage.SelectedItem.Value) {
            vldLanguages.ErrorMessage = "The base and destination languages must be different";
            e.IsValid = false;
        }
    }

    protected void btnCopyTranslations_Click(object sender, EventArgs e) {
        if(db == null || !db.Connected) {
            db = new Database();
            db.OpenConnection();
        }
        using(DbTransaction trans = db.BeginTransaction()) {
            using(Database.Command cmd = db.CreateCommand(trans)) {
                cmd.CommandText = "SELECT resourceid, translation FROM " + db.TablePrefix + "resources WHERE language = @lang";
                cmd.AddParameterWithValue("@lang", lstBaseLanguage.SelectedItem.Value);
                Dictionary<object, object> resources = new Dictionary<object, object>();
                DbDataReader reader = cmd.ExecuteReader();
                while(reader.Read()) {
                    resources.Add(reader[0], reader[1]);
                }
                reader.Close();
                BulletedList lstErrors = new BulletedList(),
                             lstSuccess = new BulletedList();
                cmd.Parameters["@lang"].Value = lstDestinationLanguage.SelectedItem.Value;
                cmd.AddParameterWithValue("@tID", "");
                cmd.AddParameterWithValue("@trans", "");
                int numCopied = 0;
                if(radIfExists.SelectedValue == "leave") {
                    cmd.CommandText = "INSERT INTO " + db.TablePrefix + "resources (resourceid, language, translation) VALUES (@tID, @lang, @trans)";
                    foreach(KeyValuePair<object, object> resource in resources) { // <resource ID, translation>
                        cmd.Parameters["@tID"].Value = resource.Key;
                        cmd.Parameters["@trans"].Value = resource.Value;
                        try {
                            cmd.ExecuteNonQuery();
                            lstSuccess.Items.Add("Copied translation for resource #" + resource.Key + "...");
                            numCopied++;
                        } catch { // errors thrown when a translation exists
                            lstSuccess.Items.Add("Translation for resource #" + resource.Key + " exists, skipping...");
                        }
                    }
                } else if(radIfExists.SelectedValue == "overwrite") {
                    switch(db.InstanceType) {
                        case Database.DatabaseType.MySQL:
                            cmd.CommandText = "INSERT INTO " + db.TablePrefix + "resources (resourceid, language, translation) VALUES (@tID, @lang, @trans) ON DUPLICATE KEY UPDATE translation = @trans";
                            break;
                        case Database.DatabaseType.SQLServer:
                            cmd.CommandText = "UPDATE " + db.TablePrefix + "resources SET translation = @trans WHERE resourceid = @tID AND language = @lang; IF @@ROWCOUNT = 0 INSERT INTO " + db.TablePrefix + "resources (resourceid, language, translation) VALUES (@tID, @lang, @trans)";
                            break;
                    }
                    foreach(KeyValuePair<object, object> resource in resources) { // <resource ID, translation>
                        cmd.Parameters["@tID"].Value = resource.Key;
                        cmd.Parameters["@trans"].Value = resource.Value;
                        try {
                            cmd.ExecuteNonQuery();
                            lstSuccess.Items.Add("Overwriting translation for resource #" + resource.Key + "...");
                            numCopied++;
                        } catch(Exception ex) { // any errors are SQL errors
                            lstErrors.Items.Add("Error adding translation for resource #" + resource.Key + ": " + ex.Message);
                        }
                    }
                }
                if(lstSuccess.Items.Count > 0) {
                    pnlSuccess.Visible = true;
                    StringBuilder buffer = new StringBuilder("<p>");
                    buffer.AppendFormat("Copied {0} translations from {1} to {2}", numCopied, lstBaseLanguage.SelectedItem.Text, lstDestinationLanguage.SelectedItem.Text).Append("</p>");
                    plcSuccess.Controls.Add(new LiteralControl(buffer.ToString()));
                    plcSuccess.Controls.Add(lstSuccess);
                }
                if(lstErrors.Items.Count > 0) {
                    pnlError.Visible = true;
                    plcErrors.Controls.Add(lstErrors);
                }
                mltMain.ActiveViewIndex = 2;
            }
            trans.Commit();
        }
    }
}
